package com.mazaiting.classfile.constant;

import com.mazaiting.classfile.constant.info.*;

/**
 * 常量信息
 *
 * @author mazaiting
 * @since 2021/8/11
 */
public class ConstantFactory {
    /**
     * 常量
     */
    public static final short CONSTANT_UTF8 = 1;
    /**
     * 整型常量
     */
    public static final short CONSTANT_INTEGER = 3;
    /**
     * 单精度型常量
     */
    public static final short CONSTANT_FLOAT = 4;
    /**
     * 长精度型常量
     */
    public static final short CONSTANT_LONG = 5;
    /**
     * 双精度型常量
     */
    public static final short CONSTANT_DOUBLE = 6;
    /**
     * 类类型常量
     */
    public static final short CONSTANT_CLASS = 7;
    /**
     * 字符串类型常量
     */
    public static final short CONSTANT_STRING = 8;
    /**
     * 字段引用常量
     */
    public static final short CONSTANT_FIELD_REF = 9;
    /**
     * 方法引用常量
     */
    public static final short CONSTANT_METHOD_REF = 10;
    /**
     * 接口方法引用常量
     */
    public static final short CONSTANT_INTERFACE_METHOD_REF = 11;
    /**
     * 名字与类型常量
     */
    public static final short CONSTANT_NAME_AND_TYPE = 12;
    /**
     * 方法句柄常量
     */
    public static final short CONSTANT_METHOD_HANDLE = 15;
    /**
     * 方法类型常量
     */
    public static final short CONSTANT_METHOD_TYPE = 16;
    /**
     * 动态方法常量
     */
    public static final short CONSTANT_INVOKE_DYNAMIC = 18;

    /**
     * 创建常量信息
     *
     * @param pool 常量池对象
     * @param tag  标识 无符号单字节
     */
    static ConstantInfo newConstantInfo(ConstantPool pool, short tag) {
        switch (tag) {
            case CONSTANT_UTF8:
                return new ConstantUtf8Info(pool, tag);
            case CONSTANT_INTEGER:
                return new ConstantIntegerInfo(pool, tag);
            case CONSTANT_FLOAT:
                return new ConstantFloatInfo(pool, tag);
            case CONSTANT_LONG:
                return new ConstantLongInfo(pool, tag);
            case CONSTANT_DOUBLE:
                return new ConstantDoubleInfo(pool, tag);
            case CONSTANT_CLASS:
                return new ConstantClassInfo(pool, tag);
            case CONSTANT_STRING:
                return new ConstantStringInfo(pool, tag);
            case CONSTANT_FIELD_REF:
                return new ConstantFiledRefInfo(pool, tag);
            case CONSTANT_METHOD_REF:
                return new ConstantMethodRefInfo(pool, tag);
            case CONSTANT_INTERFACE_METHOD_REF:
                return new ConstantInterfaceMethodRefInfo(pool, tag);
            case CONSTANT_NAME_AND_TYPE:
                return new ConstantNameAndTypeInfo(pool, tag);
            case CONSTANT_METHOD_HANDLE:
                return new ConstantMethodHandleInfo(pool, tag);
            case CONSTANT_METHOD_TYPE:
                return new ConstantMethodTypeInfo(pool, tag);
            case CONSTANT_INVOKE_DYNAMIC:
                return new ConstantInvokeDynamicInfo(pool, tag);
            default:
                throw new RuntimeException("java.lang.ClassFormatError: constant pool tag: " + tag + "!");
        }
    }

    /**
     * 校验是否占用 8 个字节
     *
     * @param tag 标识
     * @return true: 占用; false: 不占用
     */
    public static boolean checkLongOrDouble(short tag) {
        switch (tag) {
            case CONSTANT_LONG:
            case CONSTANT_DOUBLE:
                return true;
            default:
                break;
        }
        return false;
    }
}


















